package com.hx.vending.mqtt;

import com.hx.vending.bean.Equipment;
import com.hx.vending.bean.Field;
import com.hx.vending.bean.Trails;
import com.hx.vending.bean.User;
import com.hx.vending.bean.config.Constants;
import com.hx.vending.dao.*;
import com.hx.vending.util.*;
import org.apache.log4j.Logger;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.*;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;

public class PushCallback implements MqttCallback {

    private static Logger logger = Logger.getLogger(PushCallback.class); // 获取logger实例
    private ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-mybatis.xml");
    private EquipmentMapper equipmentMapper = ioc.getBean(EquipmentMapper.class);
    private UserMapper userMapper = ioc.getBean(UserMapper.class);
    private FieldMapper fieldMapper = ioc.getBean(FieldMapper.class);
    private EquipmentTypeMapper equipmentTypeMapper = ioc.getBean(EquipmentTypeMapper.class);
    private EquipmentTypeCaseMapper equipmentTypeCaseMapper = ioc.getBean(EquipmentTypeCaseMapper.class);

    private TrailsMapper trailsMapper = ioc.getBean(TrailsMapper.class);

    private RedisTemplate<String, String> redisTemplate = ioc.getBean(RedisTemplate.class);


    private ClientMQTT clientMQTT = new ClientMQTT();

    // 用于判断是否服务器执行的
    private static boolean pk = false;

    static {
        logger.error("-------------执行静态代码块---------------------");
        logger.error("-----------------首先是pk " + pk + "------------------------------");

        BufferedReader bufferedReader = null;

        File file = new File(Constant.RUNNERHEARTBEAT_FILE_PATH);

        if (file.exists()) {

            try {
                bufferedReader = new BufferedReader(new FileReader(file));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }

            String privateKey = null;

            try {
                privateKey = bufferedReader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (Constant.RUNNERHEARTBEAT_PRIVATE_KEY.equals(MD5.string2MD5(privateKey))) {

                pk = true;
                logger.error("-----------------pk值修改为 " + pk + "------------------------------");
            } else {
                logger.error("-----------------pk值没有修改,为:" + pk + "------------------------");
            }
        }

    }

    /**
     * 在断开连接时调用，主要用于重连
     *
     * @param throwable
     */
    @Override
    public void connectionLost(Throwable throwable) {
        clientMQTT.start();
    }

    /**
     * 接收订阅的消息后执行的方法
     *
     * @param topic
     * @param message
     * @throws Exception
     */
    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {

        try{

            logger.error(DateUtil.getTime() + "--------------------------- MQTT   CallBack   Start ---------------------------");

            // 判断是否服务器调用
            if (!pk) {
                logger.error("---------------------------------------------- 不是服务器调用(" + pk + ") --------------------------------------");
                return;
            }

            logger.error("接收消息主题 : " + topic + "接收消息Qos : " + message.getQos());

            logger.error("消息内容 : " + Arrays.toString(message.getPayload()));

            if (ToolUtil.isEmpty(topic) || ToolUtil.isEmpty(message)) {
                return;
            }else {
                if (ToolUtil.isEmpty(message.getPayload())) {
                    return;
                }
            }


            /**
             * 一、	终端连接服务器（主题：Connect）	终端>服务器
             * 消息内容：主板ID，随机数字（4位数）,connect,imsi,android
             * 服务器应答本消息：主板ID，随机数字（4位数），OK
             * 注：只有标记了android的设备才可以设置广告音量截屏等
             */
            if (topic.equals("Connect")) {
                logger.error("---------------------------      进入连接主题      ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                //logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1] + "主题:" + connectInformation[2]);
                if (ToolUtil.isNotEmpty(connectInformation[0]) && ToolUtil.isNotEmpty(connectInformation[1]) && ToolUtil.isNotEmpty(connectInformation[2])) {
                    if (connectInformation[2].equals("connect")) {

                        //发送应答消息
                        PubMsg.publish(connectInformation[0] + "," + connectInformation[1] + ",OK", "Connect/" + connectInformation[0]);

                        //查询设备信息
                        Equipment equipment = new Equipment();
                        equipment.setEquipmentId(connectInformation[0]);
                        Equipment selectEquipment = this.equipmentMapper.selectByPrimary(equipment);

                        //物联卡的imsi
                        if (ToolUtil.isNotEmpty(connectInformation[3])) {
                            if (connectInformation[3].equals("null")) {
                                this.equipmentMapper.updateFlowcardNull(equipment);//清空字段
                            }else {
                                equipment.setEquipmentFlowcard(connectInformation[3]);
                            }
                        }

                        //是否带屏幕
                        try {
                            if (ToolUtil.isNotEmpty(connectInformation[4])) {
                                if (connectInformation[4].equals("android")) {
                                    equipment.setEquipmentScreen(1);//有屏幕
                                }
                            }
                        } catch (Exception e) {
                            
                        }

                        int i = 0;
                        if (ToolUtil.isNotEmpty(selectEquipment)) {
                            //更新设备信息
                            equipment.setEquipmentOfflineTime("");//离线时间设为""
                            equipment.setEquipmentState("1");//1在线 2离线

                            i = this.equipmentMapper.updateByPrimaryKeySelective(equipment);
                        }else {
                            //添加新设备哦
                            equipment.setEquipmentCreateTime(DateUtil.getTime());//注册时间
                            equipment.setEquipmentOfflineTime(DateUtil.getTime());//离线时间
                            equipment.setEquipmentState("2");//1在线 2离线

                            i = this.equipmentMapper.insertSelective(equipment);
                            Equipment equi = new Equipment();
                            equi.setEquipmentId(connectInformation[0]);
                            selectEquipment = this.equipmentMapper.selectByPrimary(equi);
                        }
                        if (i != 0) {
                            if(ToolUtil.isNotEmpty(selectEquipment.getEquipmentUserId()) && ToolUtil.isNotEmpty(selectEquipment.getEquipmentFieldId())){
                                //用户
                                User u = new User();
                                u.setUserId(selectEquipment.getEquipmentUserId());
                                User user = userMapper.selectByPrimaryKey(u);
                                //场地
                                Field f = new Field();
                                f.setFieldId(selectEquipment.getEquipmentFieldId());
                                Field field = fieldMapper.selectByPrimary(f);
                                if(ToolUtil.isNotEmpty(user) && user.getUserOfflinePush().equals("1")){
                                    String pushMessage = "设备上线:\n设备ID:%s\n场地名称:%s\n场地编号:%s\n地区:%s\n详细地址:%s\n上线时间:%s\n手机号:%s";
                                    PushUtils.getInstance().pushMessage(user.getUserAccount(), String.format(pushMessage, selectEquipment.getEquipmentId(),
                                            field.getFieldName(),selectEquipment.getEquipmentNumber() + "-号机", field.getFieldRegion(), field.getFieldAddress(), DateUtil.getTime(), user.getUserAccount()));
                                }
                            }
                        }
                    }
                }
            }


            /**
             * 二、	下线遗嘱（主题：Offline）终端>服务器
             * 消息内容：主板ID，随机数字（4位数）
             * 服务器应答本消息：主板ID，随机数字（4位数），OK     不需要应答
             */
            if (topic.equals("Offline")) {
                logger.error("---------------------------      进入下线主题      ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                //logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1]);
                if (ToolUtil.isNotEmpty(connectInformation[0]) && ToolUtil.isNotEmpty(connectInformation[1])) {
                    Equipment equipment = new Equipment();
                    equipment.setEquipmentId(connectInformation[0]);
                    Equipment eqeq = equipmentMapper.selectByPrimary(equipment);
                    if (ToolUtil.isNotEmpty(eqeq) && eqeq.getEquipmentState() != "2") {
                        String time = DateUtil.getLongTime();
                        equipment.setEquipmentState("2");
                        equipment.setEquipmentOfflineTime(time);
                        equipmentMapper.updateByPrimaryKeySelective(equipment);
                        logger.error("更新设备状态为离线");

                        User user = new User();
                        user.setUserId(eqeq.getEquipmentUserId());
                        User u = userMapper.selectByPrimaryKey(user);

                        Field f = new Field();
                        f.setFieldId(eqeq.getEquipmentFieldId());
                        Field field = fieldMapper.selectByPrimary(f);
                        //开启了推送
                        if (ToolUtil.isNotEmpty(u) && u.getUserOfflinePush().equals("1")) {
                            String pushMessage = "设备离线警戒:\n设备ID:%s\n场地名称:%s\n设备编号:%s\n地区:%s\n详细地址:%s\n离线时间:%s\n手机号:%s";
                            PushUtils.getInstance().pushMessage(u.getUserAccount(), String.format(pushMessage, eqeq.getEquipmentId(),field.getFieldName(),
                                    eqeq.getEquipmentNumber()+"-号机",field.getFieldRegion(), field.getFieldAddress(), time, u.getUserAccount()));
                        }
                    }
                }
            }


            /**
             * 三、	三、	心跳包（主题：Heartbeat）		终端>服务器
             * 消息内容：主板ID，随机数字（4位数），信号强度，信号类型
             * 注：信号类型为字符串“WIFI”或”MOBILE”
             * WiFi网络下强度值为0~-100，参考
             * if (mRssi >= -50 && mRssi < 0) {          //满格
             * } else if (mRssi >= -70 && mRssi < -50) { //较强
             * } else if (mRssi >= -85 && mRssi < -70) { //较弱
             * } else if (mRssi >= -100 && mRssi < -85) { //微弱
             * }
             * Mobile网络传递level值1~5，对应移动信号几个格
             */
            if (topic.equals("Heartbeat")) {
                logger.error("---------------------------      进入心跳主题      ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                //logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1] + "信号强度:" + connectInformation[2]);

                if (ToolUtil.isNotEmpty(connectInformation[0]) && ToolUtil.isNotEmpty(connectInformation[1]) && ToolUtil.isNotEmpty(connectInformation[2])&& ToolUtil.isNotEmpty(connectInformation[3])) {
                    //查询设备信息
                    Equipment equipment = new Equipment();
                    equipment.setEquipmentId(connectInformation[0]);
                    Equipment selectEquipment = this.equipmentMapper.selectByPrimary(equipment);
                    equipment.setEquipmentSignal(Integer.parseInt(connectInformation[2]));
                    equipment.setEquipmentSignalType(connectInformation[3]);

                    if (ToolUtil.isNotEmpty(selectEquipment)) {
                        //如果当前设备存在，更新设备信息
                        equipment.setEquipmentState("1");//心跳包存在，设备在线  1在线  2离线
                        equipment.setEquipmentOfflineTime("");//在线时,离线时间为""
                        equipment.setEquipmentHeartTime(DateUtil.getTime());

                        this.equipmentMapper.updateByPrimaryKeySelective(equipment);
                    }
                }
            }


            /**
             * 四、	出货指令（主题：Delivery）服务器>终端
             * 消息内容：主板ID，随机数字（4位数），出货货道号，出货数量
             * 终端应答（主题：DeliveryReceive）：主板ID，随机数字（4位数），出货货道号，出货数量
             */
            if (topic.equals("DeliveryReceive")) {
                logger.error("---------------------------    进入出货应答主题    ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                //logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1]);

                if (ToolUtil.isNotEmpty(connectInformation[0])) {
                    //保存应答消息
                    redisTemplate.boundValueOps("DeliveryReceive-" + connectInformation[0]).set(connectMessage, Constants.MQTT_EXPIRES_HOUR, TimeUnit.SECONDS);
                }
            }


            /**
             * 4.1出货成功(主题: DeliverySuccess) 终端->服务器
             * 消息内容: 主板ID，随机数字（4位数），出货货道号，出货数量
             * 终端应答:（主题：DeliverySuccessReceive）：主板ID，原随机数字，出货货道号，出货数量
             */
            if (topic.equals("DeliverySuccess")) {
                logger.error("---------------------------    进入出货成功主题    ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                //logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1]);

                if (ToolUtil.isNotEmpty(connectInformation[0])) {
                    //发送应答消息
                    PubMsg.publish(connectMessage, "DeliverySuccessReceive/" + connectInformation[0]);

                    //保存数据
                    redisTemplate.boundValueOps("DeliverySuccess-" + connectInformation[0]).set(connectMessage, Constants.MQTT_EXPIRES_HOUR, TimeUnit.SECONDS);
                }
            }


            /**
             * 4.2 主动刷新商品及库存数据（主题RefreshGoods）服务器->终端
             * 消息内容: 主板ID，随机数字（4位数）
             * 终端应答:（主题：RefreshGoodsReceive）：主板ID，原随机数字，
             * (该协议用于后台补货完成后通知数据刷新)
             */
            if (topic.equals("RefreshGoodsReceive")) {
                logger.error("---------------------------    进入刷新商品主题    ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                //logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1]);

                if (ToolUtil.isNotEmpty(connectInformation[0])) {
                    //保存数据
                    redisTemplate.boundValueOps("RefreshGoods-" + connectInformation[0]).set(connectMessage, Constants.MQTT_EXPIRES_HOUR, TimeUnit.SECONDS);
                }
            }


            /**
             * 五、故障上传（主题：Alarm）终端>服务器
             * 消息内容：主板ID，随机数字（4位数）,故障码, 货道位置, 货道类型，所在机箱
             * 服务器应答：（主题：AlarmReceive）主板ID，随机数字（4位数）,故障码, 货道位置, 货道类型，所在机箱
             */
            if (topic.equals("Alarm")) {
                logger.error("---------------------------    进入故障上传主题    ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                //logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1] + "故障码:" + connectInformation[2] + "货道位置:" + connectInformation[3]);

                logger.error(connectMessage);
                if (ToolUtil.isNotEmpty(connectInformation[0]) && ToolUtil.isNotEmpty(connectInformation[1]) && ToolUtil.isNotEmpty(connectInformation[2]) && ToolUtil.isNotEmpty(connectInformation[3]) && ToolUtil.isNotEmpty(connectInformation[5])) {
                    //保存消息
                    redisTemplate.boundValueOps("Alarm-" + connectInformation[0]).set(connectMessage, Constants.MQTT_EXPIRES_HOUR, TimeUnit.SECONDS);

                    //查询设备信息
                    Equipment equipment = new Equipment();
                    equipment.setEquipmentId(connectInformation[0]);
                    Equipment selectEquipment = this.equipmentMapper.selectByPrimary(equipment);

                    if (ToolUtil.isNotEmpty(selectEquipment)) {

                        //更改货道故障信息
                        Trails trails = new Trails();
                        trails.setTrailsEquipmentId(connectInformation[0]);
                        trails.setTrailsPosition(connectInformation[3]);
                        trails.setTrailsCaseId(Integer.parseInt(connectInformation[5]));
                        Trails selectTrails = this.trailsMapper.selectByPrimaryKeySelective(trails);
                        if (ToolUtil.isNotEmpty(selectTrails)) {
                            trails.setTrailsId(selectTrails.getTrailsId());
                            trails.setTrailsAlarm(Integer.parseInt(connectInformation[2]));//故障码
                            this.trailsMapper.updateByPrimaryKeySelective(trails);
                        }

                        equipment.setEquipmentCurrentState("3");//故障
                        //更新设备故障
                        int i = this.equipmentMapper.updateByPrimaryKeySelective(equipment);

                        User user = new User();
                        user.setUserId(selectEquipment.getEquipmentUserId());
                        User selectUser = this.userMapper.selectByPrimaryKey(user);

                        Field f = new Field();
                        f.setFieldId(selectEquipment.getEquipmentFieldId());
                        Field field = fieldMapper.selectByPrimary(f);

                        if (i != 0) {
                            //发送应答消息
//                            byte[] bytes = ByteUtils.get().add(connectInformation[0] + "," + connectInformation[1] + ",OK").toArray();
//                    clientMQTT.getClient().publish("Alarm", bytes, 0, false);
                            //PubMsg.publish(connectInformation[0] + "," + connectInformation[1] + "," + connectInformation[2] + ",OK", "AlarmReceive/" + connectInf
                            PubMsg.publish(connectMessage, "AlarmReceive/" + connectInformation[0]);
                        }
                        String position = connectInformation[3];

                        String rise = position.substring(0,2);
                        if (Integer.parseInt(rise.substring(0,1)) == 0){
                            Integer r = Integer.parseInt(rise.substring(1)) + 1;
                            if(r < 10){
                                rise = "0"+r;
                            }else {
                                rise = r + "";
                            }
                        }else {
                            Integer r = Integer.parseInt(rise) + 1;
                            rise = r + "";
                        }
                        String trails1 = position.substring(2);
                        if(Integer.parseInt(trails1.substring(0,1)) == 0){
                            Integer r = Integer.parseInt(trails1.substring(1)) + 1;
                            if(r < 10){
                                trails1 = "0"+r;
                            }else {
                                trails1 = r + "";
                            }
                        }else{
                            Integer r = Integer.parseInt(trails1) + 1;
                            trails1 = r + "";
                        }
                        String str = "";
                        //故障码
                        String breakDown = connectInformation[2];
                        if(breakDown.equals("1")){
                            str = "开关未弹起，当前出于故障状态，测试调整后再使用";
                        }else if (breakDown.equals("2")){
                            str = "该货道电机断线故障";
                        }else if (breakDown.equals("3")){
                            str = "5s内开关无断开动作";
                        }else if (breakDown.equals("4")){
                            str = "5s内开关无接通动作";
                        }else if (breakDown.equals("5")){
                            str = "副箱无应答(应答超时时间20秒)";
                        }else if (breakDown.equals("6")){
                            str = "格子柜返回货道类型错误";
                        }else if (breakDown.equals("7")){
                            str = "格子柜未打开或检测开关异常";
                        }

                        //开启了推送
                        if (selectUser != null) {
                            String pushMessage = "设备故障警戒:\n设备ID:%s\n场地名称:%s\n详细地址:%s\n场地机号:%s\n货道位置:%s\n故障原因:%s\n" +
                                    "剩余库存:%s\n故障时间:%s\n请尽快及时处理!";
                            PushUtils.getInstance().pushMessage(selectUser.getUserAccount(), String.format(pushMessage, equipment.getEquipmentId(),
                                    field.getFieldName(),field.getFieldAddress(),selectEquipment.getEquipmentNumber() + "-号机","第"+rise+"层，第"+trails1+"货道",
                                    str,selectTrails.getTrailsGoodsStock(),DateUtil.getTime()));
                        }
                    }
                }
            }


            /**
             * 六、	恢复出厂设置（主题：Restore）服务器>终端
             * 消息内容：主板ID，随机数字（4位数）,restore
             * 终端应答：主板ID，随机数字（4位数），OK
             */
            if (topic.equals("Restore")) {
                logger.error("---------------------------    进入恢复出厂主题    ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                //logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1] + "OK:" + connectInformation[2]);

                if (ToolUtil.isNotEmpty(connectInformation[0]) && ToolUtil.isNotEmpty(connectInformation[1]) && ToolUtil.isNotEmpty(connectInformation[2])) {
                    if (connectInformation[2].equals("OK")) {
                        //保存应答消息
                        redisTemplate.boundValueOps("Restore-" + connectInformation[0]).set(connectMessage, Constants.MQTT_EXPIRES_HOUR, TimeUnit.SECONDS);
                    }
                }
            }


            /**
             * 七、	下发设置参数（主题：DownLoadSetting）服务器>终端
             * 消息内容：主板ID，随机数字（4位数），设置参数，协议待定
             * 终端应答：主板ID，随机数字（4位数），OK
             */
            if (topic.equals("DownLoadSetting")) {
                logger.error("---------------------------  进入下发设置参数主题  ---------------------------");

//                String connectMessage = new String(message.getPayload());
//                String[] connectInformation = connectMessage.split(",");
//
//                //logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1] + "OK:" + connectInformation[2]);
//
//                if (connectInformation[2].equals("OK")) {
//                    //保存应答消息
//                    redisTemplate.boundValueOps("DownLoadSetting-" + connectInformation[2]).set(connectMessage, Constants.MQTT_EXPIRES_HOUR, TimeUnit.SECONDS);
//                }
            }


            /**
             * 八、	位置信息上传（主题：Position）终端>服务器
             * 消息内容：主板ID，随机数字（4位数），经度，纬度，地址描述
             * 服务器端应答（PositionReceive）：主板ID，原随机数字
             * 注：终端开机后，主动上传一次位置信息。
             */
            if (topic.equals("Position")) {
                logger.error("---------------------------  进入位置信息上传主题  ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                //logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1] + "经度:" + connectInformation[2] + "纬度:" + connectInformation[3] + "地址描述:" + connectInformation[4]);

                if (ToolUtil.isNotEmpty(connectInformation[0]) && ToolUtil.isNotEmpty(connectInformation[1]) && ToolUtil.isNotEmpty(connectInformation[2]) && ToolUtil.isNotEmpty(connectInformation[3]) && ToolUtil.isNotEmpty(connectInformation[4])) {

                    //发送应答消息
                    PubMsg.publish(connectInformation[0] + "," + connectInformation[1], "PositionReceive/" + connectInformation[0]);

                    //保存设备位置信息
                    Equipment equipment = new Equipment();
                    equipment.setEquipmentId(connectInformation[0]);
                    equipment.setEquipmentPositionLongitude(connectInformation[2]);
                    equipment.setEquipmentPositionLatitude(connectInformation[3]);
                    equipment.setEquipmentPositionDescribe(new String(connectInformation[4]));
                    //new String(content.getBytes("iso-8859-1"),"utf-8")
                    this.equipmentMapper.updateByPrimaryKeySelective(equipment);
                }

            }


            /**
             * 九、	上传设置参数（主题：UpLoadSetting）终端>服务c 器
             * 消息内容：主板ID，随机数字（4位数），设置参数，协议待定
             * 终端应答：主板ID，随机数字（4位数），OK
             * 注：终端开机时，主动上传一次设置参数。之后当在线下设置时或者设置有变化时，主动上传设置信息
             */
            if (topic.equals("UpLoadSetting")) {
                logger.error("---------------------------  进入上传设置参数主题  ---------------------------");

//                String connectMessage = new String(message.getPayload());
//                String[] connectInformation = connectMessage.split(",");
//
//                //logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1] + "设置参数:" + connectInformation[2]);
//
//                //发送应答消息
//                byte[] bytes = ByteUtils.get().add(connectInformation[0] + "," + connectInformation[1] + ",OK").toArray();
//                clientMQTT.getClient().publish("UpLoadSetting", bytes, 0, false);
            }


            /**
             * 十、	反扫器充值到终端（主题：OnLinePay）终端>服务器
             * 消息内容：主板ID，随机数字（4位数），玩家openID，充值金额
             * 服务器应答：主板ID，随机数字（4位数），玩家openID，充值金额，OK
             * 注：终端收到服务器的应答后，充值到终端。
             */
            if (topic.equals("OnLinePay")) {
                logger.error("---------------------------进入反扫器充值到终端主题---------------------------");

//                String connectMessage = new String(message.getPayload());
//                String[] connectInformation = connectMessage.split(",");
//
//                //logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1] + "OPENID:" + connectInformation[2] + "充值金额:" + connectInformation[3]);
//
//                //发送应答消息
//                byte[] bytes = ByteUtils.get().add(connectInformation[0] + "," + connectInformation[1] + "," + connectInformation[2] + "," + connectInformation[3] + ",OK").toArray();
//                clientMQTT.getClient().publish("OnLinePay", bytes, 0, false);
            }


            /**
             * 十一、	暂停终端使用（主题：SetUse）服务器>终端
             * 消息内容：主板ID，随机数字（4位数）,useable/unuseable(可用/不可用)
             * 终端应答：主板ID，随机数字（4位数），OK
             * 注：暂停终端使用时，不影响心跳包的上传。
             */
            if (topic.equals("SetUse")) {
                logger.error("---------------------------进入暂停开启终端使用主题---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                //logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1] + "OK:" + connectInformation[2]);

                if (ToolUtil.isNotEmpty(connectInformation[0]) && ToolUtil.isNotEmpty(connectInformation[1]) && ToolUtil.isNotEmpty(connectInformation[2])) {
                    if (connectInformation[2].equals("OK")) {
                        //保存应答消息
                        redisTemplate.boundValueOps("Useable-" + connectInformation[0]).set(connectMessage, Constants.MQTT_EXPIRES_HOUR, TimeUnit.SECONDS);
                    }
                }
            }

            /**
             * 十二、	更新终端广告图片视频（主题：ChangeBanner）服务器>终端
             * 消息内容：主板ID，随机数字（4位数），change
             * 终端应答：主板ID，随机数字（4位数），OK
             * 注：原更新产品图片去掉，功能由4.2完成，此主题用于通知终端刷新轮播图
             */
            if (topic.equals("ChangeBanner")) {

                logger.error("---------------------------    进入更新广告主题    ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                //logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1] + "OK:" + connectInformation[2]);

                if (ToolUtil.isNotEmpty(connectInformation[0]) && ToolUtil.isNotEmpty(connectInformation[1]) && ToolUtil.isNotEmpty(connectInformation[2])) {
                    if (connectInformation[2].equals("OK")) {
                        //保存应答消息
                        redisTemplate.boundValueOps("ChangeBanner-" + connectInformation[0]).set(connectMessage, Constants.MQTT_EXPIRES_HOUR, TimeUnit.SECONDS);
                    }
                }
            }


            /**
             * 十五、货道测试（主题TestMouth）服务器 -> 终端
             * 消息内容：主板ID，4位随机数字，测试货道号，出货数量，货道类型，所在机箱
             * 终端应答：（TestMouthReceive）内容同上
             * 注：后期在手机端实现测试功能
             * 履带时“出货数量”表示旋转时间，时间单位待定
             */
            if (topic.equals("TestMouthReceive")) {

                logger.error("---------------------------    进入货到测试主题    ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                if (ToolUtil.isNotEmpty(connectInformation[0]) && ToolUtil.isNotEmpty(connectInformation[1]) && ToolUtil.isNotEmpty(connectInformation[2])) {
                    //保存应答消息
                    redisTemplate.boundValueOps("TestMouthReceive-" + connectInformation[0]).set(connectMessage, Constants.MQTT_EXPIRES_HOUR, TimeUnit.SECONDS);
                }

            }

            /**
             * 十六、测试结果（主题TestResult）终端 -> 服务器
             * 消息内容：主板ID，4位随机数字，测试货道号，测试结果，货道类型，所在机箱
             * 服务器应答：（TestResultReceive）主板ID，4位随机数字，测试货道号，测试结果，货道类型，所在机箱
             * 注：结果 0 正常，其他参照故障码
             * 故障码1：此层至少一个货道的检测开关故障，或者卡货
             * 故障码2：此层货道电机断线故障
             * 故障码3：5s内开关无断开动作，此层货道故障，未修复前停止使用。
             * 故障码4：5s内开关无接通动作，此层货道故障，未修复前停止使用。
             * 故障码5：副箱无应答（应答超时时间20秒）
             * 故障码6：格子柜返回货道类型错误
             * 故障码7：格子柜未打开或检测开关异常
             */
            if (topic.equals("TestResult")) {
                logger.error("---------------------------  进入货道测试结果主题  ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                //logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1] + "货道号:" + connectInformation[2] + "结果:" + connectInformation[3]);

                if (ToolUtil.isNotEmpty(connectInformation[0]) && ToolUtil.isNotEmpty(connectInformation[1]) && ToolUtil.isNotEmpty(connectInformation[2]) && ToolUtil.isNotEmpty(connectInformation[3])&&
                        ToolUtil.isNotEmpty(connectInformation[4]) && ToolUtil.isNotEmpty(connectInformation[5])) {

                    //发送应答消息
                    PubMsg.publish(connectMessage, "TestResultReceive/" + connectInformation[0]);

                    //保存数据
                    redisTemplate.boundValueOps("TestResult-" + connectInformation[0]).set(connectMessage, Constants.MQTT_EXPIRES_HOUR, TimeUnit.SECONDS);

                    //查询货道信息
                    Trails trails = new Trails();
                    trails.setTrailsEquipmentId(connectInformation[0]);//设备id
                    trails.setTrailsPosition(connectInformation[2]);//货道位置
                    trails.setTrailsCaseId(Integer.parseInt(connectInformation[5]));//机箱
                    Trails selectTrails = this.trailsMapper.selectByPrimaryKeySelective(trails);
                    if (ToolUtil.isNotEmpty(selectTrails)) {
                        if (!selectTrails.getTrailsAlarm().toString().equals(connectInformation[3])) {
                            selectTrails.setTrailsAlarm(Integer.parseInt(connectInformation[3]));//故障码
                            this.trailsMapper.updateByPrimaryKeySelective(selectTrails);
                        }
                    }
                }
            }


            /**
             * 十七、调整终端音量(主题：AdjustAudioSuccess)服务器>终端
             * 消息内容:主板id，4位随机数字，设置方向（raise/lower）
             * 终端应答（AdjustAudioSuccess）：主板id，4位随机数字，当前音量
             */
            if (topic.equals("AdjustAudioSuccess")) {
                logger.error("---------------------------  进入调整终端音量主题  ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                if (ToolUtil.isNotEmpty(connectInformation[0]) && ToolUtil.isNotEmpty(connectInformation[1])) {

                    //保存数据
                    redisTemplate.boundValueOps("AdjustAudio-" + connectInformation[0]).set(connectMessage, Constants.MQTT_EXPIRES_HOUR, TimeUnit.SECONDS);
                }
            }

            /**
             * 十八、上传屏幕截图（主题：UploadShot）服务器》终端
             * 消息内容：主板id。随机数字（4位数），shot
             * 终端应答（UploadShotReceive）：主板id，随机数字（4位数），OK
             */
            if (topic.equals("UploadShotReceive")) {
                logger.error("---------------------------  进入上传屏幕截图主题  ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                if (ToolUtil.isNotEmpty(connectInformation[0]) && ToolUtil.isNotEmpty(connectInformation[1])) {

                    //保存数据
                    redisTemplate.boundValueOps("UploadShot-" + connectInformation[0]).set(connectMessage, Constants.MQTT_EXPIRES_HOUR, TimeUnit.SECONDS);
                }
            }
            /**
             * 十九、上传摄像头拍照（主题：UploadPhoto）服务器》终端
             * 消息内容：主板id。随机数字（4位数）
             * 终端应答（UploadPhotoReceive）：主板id，随机数字（4位数），OK
             */
            if (topic.equals("UploadPhotoReceive")) {
                logger.error("--------------------------- 进入上传摄像头拍照主题 ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                if (ToolUtil.isNotEmpty(connectInformation[0]) && ToolUtil.isNotEmpty(connectInformation[1])) {

                    //保存数据
                    redisTemplate.boundValueOps("UploadPhoto-" + connectInformation[0]).set(connectMessage, Constants.MQTT_EXPIRES_HOUR, TimeUnit.SECONDS);
                }
            }

            /**
             * 二十、异常震动报警上传（主题：VibrateAlarm）终端>服务器
             * 消息内容：主板ID，随机数字（4位数），Vibrate
             * 服务器端应答（PositionReceive）：同上
             */
            if (topic.equals("VibrateAlarm")) {
                logger.error("---------------------------  进入异常震动报警主题  ---------------------------");

                String connectMessage = new String(message.getPayload());
                String[] connectInformation = connectMessage.split(",");

                logger.error("主板id:" + connectInformation[0] + "随机数:" + connectInformation[1] + "报警:" + connectInformation[2]);

                if (ToolUtil.isNotEmpty(connectInformation[0]) && ToolUtil.isNotEmpty(connectInformation[1]) && ToolUtil.isNotEmpty(connectInformation[2])) {

                    //发送应答消息
                    PubMsg.publish(connectMessage, "VibrateAlarmReceive/" + connectInformation[0]);

                    Equipment equipment = equipmentMapper.selectById(connectInformation[0]);
                    User user = userMapper.selectUserById(equipment.getEquipmentUserId());
                    Field field = fieldMapper.selectFildById(equipment.getEquipmentFieldId());
                    if(ToolUtil.isNotEmpty(user)){
                        String pushMessage = "设备异常震动报警:\n设备ID:%s\n场地名称:%s\n场地机号:%s\n请尽快及时处理!";
                        PushUtils.getInstance().pushMessage(user.getUserAccount(), String.format(pushMessage, equipment.getEquipmentId(),field.getFieldName(),
                                equipment.getEquipmentNumber()+"-号机"));
                    }
                }

            }



            logger.error(DateUtil.getTime() + "--------------------------- MQTT  CallBack  Stop ----------------------------");
        }catch (Exception e){
            logger.error("接收消息异常");
            logger.error(e);
        }



    }

    /**
     * 接收到已经发布的 QoS 1 或 QoS 2 消息的传递令牌时调用
     *
     * @param token
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
        logger.error("deliveryComplete---------" + token.isComplete());
    }


}
